package session

import (
	"context"
	"net/http"
)

// session 可以从 web 框架中独立出来
// 为了与框架解耦，context 参数一律使用标准库的

// session 用于操作具体的键值对数据
type Session interface {
	Get(ctx context.Context, key string) (any, error)
	Set(ctx context.Context, key string, val any) error
	ID() string
}

// store 用于管理 session 的生命周期
// 所有方法都要求传入 session id，因为它可以从请求参数中获取
type Store interface {
	// id 可以在 store 内部自动生成，也可以由使用者指定，只要是唯一的就行
	// id 中有可能会把一些热点数据编码进去，以减轻数据读取压力，这是业务强相关的，最好交给用户去做
	// session 对象的创建和获取最好分开到不同的方法中处理，因为获取的时候要处理确实不存在的情况
	Generate(ctx context.Context, id string) (Session, error)
	Get(ctx context.Context, id string) (Session, error)
	Refresh(ctx context.Context, id string) error
	Remove(ctx context.Context, id string) error
}

// propagator 用于 cookie 和 session 的连接
type Propagator interface {
	// 从 cookie 中把 session id 拿出来
	Extract(req *http.Request) (string, error)
	// 把 session id 写到 cookie 中
	Inject(id string, writer http.ResponseWriter) error
	// 删掉 cookie
	Remove(writer http.ResponseWriter) error
}
